package cn.virens.web.controller.manage.sys;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.virens.common.MapUtil;
import cn.virens.common.RequestUtil;
import cn.virens.components.page.PageParamUser;
import cn.virens.components.page.PageResult;
import cn.virens.database.common.TransactionExecute;
import cn.virens.database.enums.UserType;
import cn.virens.database.mysql.model.sys.SysUser;
import cn.virens.database.mysql.model.sys.SysUserBind;
import cn.virens.exception.APIException;
import cn.virens.service.inter.sys.SysUserService;
import cn.virens.service.inter.sys.user.SysUserGroupRelationService;
import cn.virens.service.inter.sys.user.SysUserGroupService;
import cn.virens.service.inter.sys.user.SysUserRoleRelationService;
import cn.virens.service.inter.sys.user.SysUserRoleService;
import cn.virens.web.common.BaseTableController;

/**
 * 用户管理 - sys_user
 *
 * @author Virens
 * @since  2018-08-25 15:39:30
 */
@Controller
@RequestMapping("/manage/sys/user")
public class SysUserContorller extends BaseTableController<SysUser, SysUserService> {
	private @Autowired SysUserGroupRelationService mSysUserGroupRelationService;
	private @Autowired SysUserRoleRelationService mSysUserRoleRelationService;
	private @Autowired SysUserGroupService mSysUserGroupService;
	private @Autowired SysUserRoleService mSysUserRoleService;
	private @Autowired TransactionExecute mTransactionExecute;

	public SysUserContorller() {
		super("/manage/sys/user", "sys:user");
		super.disable(API_CREATE, API_UPDATE);
	}

	@Override
	public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
		String answer = super.index(request, response, model);

		model.addAttribute("groups", mSysUserGroupService.selectAll());
		model.addAttribute("roles", mSysUserRoleService.selectAll());

		return answer;
	}

	@RequestMapping("view.jspx")
	public String viewJspx(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response, Model model) {
		model.addAttribute("groups", mSysUserGroupRelationService.getGroupList(id));
		model.addAttribute("roles", mSysUserRoleRelationService.getRoleList(id));
		model.addAttribute("bindList", mBaseService.bindSelect(id));
		model.addAttribute("record", mBaseService.selectOne(id));

		return returnUrl("view");
	}

	@RequestMapping("create.jspx")
	public String createJspx(HttpServletRequest request, HttpServletResponse response, Model model) {
		model.addAttribute("groups", mSysUserGroupService.selectAll());
		model.addAttribute("roles", mSysUserRoleService.selectAll());
		model.addAttribute("types", UserType.values());

		return returnUrl("create");
	}

	@RequestMapping("update.jspx")
	public String updateJspx(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response, Model model) {
		List<Map<String, Object>> groupList = mSysUserGroupRelationService.getGroupList(id);
		List<Map<String, Object>> roleList = mSysUserRoleRelationService.getRoleList(id);

		model.addAttribute("groupValue", pasre(model, "groupDef", groupList));
		model.addAttribute("roleValue", pasre(model, "roleDef", roleList));
		model.addAttribute("groups", mSysUserGroupService.selectAll());
		model.addAttribute("roles", mSysUserRoleService.selectAll());
		model.addAttribute("record", mBaseService.selectOne(id));

		return returnUrl("update");
	}

	@ResponseBody
	@RequestMapping(value = "save.json", params = "oper=password")
	public Model password(HttpServletRequest request, HttpServletResponse response, Model model) {
		SysUserBind bind = new SysUserBind();
		bind.setUuid(RequestUtil.getValueStr(request, "uuid"));
		bind.setPasswordSrc(RequestUtil.getValueStr(request, "password"));

		if (mBaseService.bindUpdate(bind) != null) {
			return renderSuccess(model, "修改成功");
		} else {
			return renderFail(model, "修改失败");
		}
	}

	@ResponseBody
	@RequestMapping(value = "save.json", params = "oper=create0")
	public Model createJSON(@RequestBody JSONObject json, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
		return mTransactionExecute.write((s) -> {
			SysUserBind bind = new SysUserBind();
			bind.setType(json.getInteger("type"));
			bind.setAccount(json.getString("account"));
			bind.setPasswordSrc(json.getString("password"));

			SysUser record = json.toJavaObject(SysUser.class);
			if (mBaseService.insert(record, bind) != null) {

				JSONArray role = json.getJSONArray("roleList");
				if (putRoleList(record.getUuid(), role) <= 0) {//
					throw new APIException("ERROR_ROLE", "保存角色信息失败");
				}

				JSONArray group = json.getJSONArray("groupList");
				if (putGroupList(record.getUuid(), group) <= 0) {//
					throw new APIException("ERROR_ROLE", "保存用户组信息失败");
				}

				return renderSuccess(model, "添加成功");
			} else {
				return renderFail(model, "添加失败");
			}
		});
	}

	@ResponseBody
	@RequestMapping(value = "save.json", params = "oper=update0")
	public Model updateJSON(@RequestBody JSONObject json, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
		return mTransactionExecute.write((s) -> {
			SysUser record = json.toJavaObject(SysUser.class);
			if (mBaseService.update(record, record.getUuid()) != null) {

				JSONArray role = json.getJSONArray("roleList");
				if (putRoleList(record.getUuid(), role) <= 0) {//
					throw new APIException("ERROR_ROLE", "保存角色信息失败");
				}

				JSONArray group = json.getJSONArray("groupList");
				if (putGroupList(record.getUuid(), group) <= 0) {//
					throw new APIException("ERROR_ROLE", "保存用户组信息失败");
				}

				return renderSuccess(model, "更新成功");
			} else {
				return renderFail(model, "更新失败");
			}
		});
	}

	@Override
	protected PageResult<?> listHandle(HttpServletRequest request, PageParamUser page) throws Exception {
		page.addParam("group", RequestUtil.getValueStr(request, "group", null));
		page.addParam("role", RequestUtil.getValueStr(request, "role", null));
		page.addParam("name", RequestUtil.getValueStr(request, "name", null));

		return super.listHandle(request, page);
	}

	@Override
	protected Serializable toId(String id) {
		return id;
	}

	private List<Object> pasre(Model model, String key, List<Map<String, Object>> groupList) {
		List<Object> answerList = new ArrayList<>();

		for (Map<String, Object> item : groupList) {
			answerList.add(item.get("identity"));

			if (MapUtil.getBooleanValue(item, "isdefault")) {
				model.addAttribute(key, item.get("identity"));
			}
		}

		return answerList;
	}

	private int putRoleList(String uuid, JSONArray array) {
		return mSysUserRoleRelationService.putRoleList(uuid, array);
	}

	private int putGroupList(String uuid, JSONArray array) {
		return mSysUserGroupRelationService.putGroupList(uuid, array);
	}

}
